package com.hgyc.mom.mes.websocket.service;

import com.hgyc.mom.common.util.StringUtils;
import com.hgyc.mom.mes.enums.SopTerminalStatusEnum;
import com.hgyc.mom.mes.service.SopTerminalService;
import com.hgyc.mom.mes.websocket.util.SemaphoreUtils;
import com.hgyc.mom.mes.websocket.util.WebSocketUsers;
import jakarta.websocket.Session;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.concurrent.Semaphore;

@Slf4j
@Service
public class ConnectionManager {

    private final SopTerminalService sopTerminalService;
    private static final int MAX_CONNECTIONS = 1000;
    private static final Semaphore socketSemaphore = new Semaphore(1000);

    public ConnectionManager(SopTerminalService sopTerminalService) {
        this.sopTerminalService = sopTerminalService;
    }

    public void handleOpen(Session session, String ip) {
        if (!StringUtils.isNotNull(ip) || "undefined".equals(ip)) {
            close(session, "无效IP");
            return;
        }

        boolean acquired = SemaphoreUtils.tryAcquire(socketSemaphore);
        if (!acquired) {
            WebSocketUsers.sendMessage(session, "连接数超限：" + MAX_CONNECTIONS);
            close(session, "连接数超限");
            return;
        }

        try {
            WebSocketUsers.put(ip, session);
            WebSocketUsers.sendMessage(session, "连接成功");
            sopTerminalService.updateTerminalByIP(ip, SopTerminalStatusEnum.ON_LINE);
        } catch (Exception e) {
            log.error("WebSocket 建立连接失败", e);
            close(session, "连接失败");
        } finally {
            if (!WebSocketUsers.contains(ip)) {
                SemaphoreUtils.release(socketSemaphore);
            }
        }
    }

    public void handleClose(Session session) {
        String ip = WebSocketUsers.getKeyBySession(session);
        WebSocketUsers.remove(session);
        SemaphoreUtils.release(socketSemaphore);

        // 更新设备状态为离线
        if (ip != null) {
            sopTerminalService.updateTerminalByIP(ip, SopTerminalStatusEnum.OFF_LINE);
        }
    }

    public void handleError(Session session, Throwable throwable) {
        String ip = WebSocketUsers.getKeyBySession(session);

        log.error("WebSocket 出现异常", throwable);
        WebSocketUsers.remove(session);
        SemaphoreUtils.release(socketSemaphore);

        if (ip != null) {
            sopTerminalService.updateTerminalByIP(ip, SopTerminalStatusEnum.OFF_LINE);
        }

        try {
            if (session.isOpen()) session.close();
        } catch (Exception ignored) {}
    }

    private void close(Session session, String reason) {
        try {
            if (session.isOpen()) session.close();
        } catch (Exception ignored) {}
        log.warn("连接关闭: {}, 原因: {}", session.getId(), reason);
    }
}
